'This is the main module for the program.
'This contains all the startup procedures and how to handle the different
'Command-line options
''' -----------------------------------------------------------------------------
''' <summary>
''' This contains all the global info and methods for Codename: STIMPy!
''' </summary>
''' <remarks>
'''     
''' </remarks>
''' <history>
''' 	[Jason Schreckengost]	8/6/2006	Created
''' </history>
''' -----------------------------------------------------------------------------
Module modMain
    'This region contains all variables used in the module and program
#Region "Variables"

    'Declare frmServer as the Form1 datatype
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks>
    ''' a global variable
    ''' </remarks>
    ''' <history>
    ''' 	[Jas]	8/6/2006	Created
    ''' </history>
    ''' <todo>
    ''' Make this variable global to app but not Public
    ''' </todo>
    ''' -----------------------------------------------------------------------------
    Public frmServer As Form1
    'Declare App as the clsMain datatype and instantiate it
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' The new App class (similar to App.* in VB6)
    ''' </summary>
    ''' <remarks>
    ''' 
    ''' </remarks>
    ''' <history>
    ''' 	[Jas]	8/6/2006	Created
    ''' </history>
    ''' <todo>
    ''' Make this variable global to app but not Public
    ''' </todo>
    ''' -----------------------------------------------------------------------------
    Public App As New clsMain
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Jas]	8/6/2006	Created
    ''' </history>
    ''' <todo>
    ''' Make this variable global to app but not Public
    ''' </todo>
    ''' -----------------------------------------------------------------------------
    Public Users() As clsUser

    Public htUsers As Hashtable = New Hashtable

    Private thdCleanUpUsers As Threading.Thread 
    Private thdFindOpenUser As Threading.Thread
    Public U1ArrList As ArrayList = New ArrayList
    Private sBackLog As String
    '!' MySQLCon MUST stay the last delcaration
    Private mySQLCon As clsMySQL

#End Region 'Variables
    'This region contains the Methods (Subs and Functions)
    ' used in the module and program
#Region "Methods"
    ' Usage: None (Automatically called at startup)
    ' This is our Main start up SubRoutine
    ' Options:
    '   -console
    '       Use this to restrict the GUI from being shown.
    '       This option uses significantly less resources
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="args"></param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Jason Schreckengost]	6/25/2006	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Sub Main(ByVal args() As String)
        'Threading.Thread.CurrentThread.Priority = Threading.ThreadPriority.Lowest
        'sBackLog = vbNullString
        mySQLCon = New clsMySQL
        ReDim Preserve Users(0)
        'Users(0) = New clsUser
        mySQLCon.MySQLCommand("UPDATE `users` SET `logged`=NULL WHERE 1")
        mySQLCon.Close()
        'Check for -console
        If args.IndexOf(args, "console") >= 0 Then

            'If -console was selected, run the following code
            'Tell the program we are using the console
            App.Console = True

            'debug
            MsgBox("Console was selected")

        Else 'No -console

            'If -console was not selected, run the following code
            'Tell the program we are using the GUI
            App.Console = False

            'Set frmServer to an instance of Form1 (our server GUI)
            frmServer = New Form1

            'Run the form on the current thread
            Application.Run(frmServer)

        End If '-console

    End Sub 'Main
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="data"></param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Jason Schreckengost]	6/25/2006	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub Display(ByVal data As String)
        If (App.Console) Then
            Console.Write(data)
        Else
            If frmServer Is Nothing Then
                If sBackLog Is Nothing Then
                    sBackLog = data
                Else
                    sBackLog += vbNewLine + data
                End If
            Else
                SyncLock frmServer.txtLog.Text
                    With frmServer.txtLog
                        If Not sBackLog Is Nothing Then
                            .Text += vbNewLine + sBackLog
                            sBackLog = vbNullString
                        End If

                        If Not data = vbNullString Then .Text += vbNewLine + data
                        .SelectionStart = .Text.Length
                        '.SelectedText = .Text
                        .ScrollToCaret()
                    End With
                End SyncLock
            End If
        End If

    End Sub
    'This function is used to find an open slot in the Users array.
    'If one is not found, it creates one.
    'Either way, it will return the index of the array element
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Jason Schreckengost]	6/25/2006	Created
    '''     [Jason Schreckengost]   8/6/2006    Merged CleanUpUsers
    ''' </history>
    ''' <todo>
    ''' Find some info about ping class...(2005 only?)
    ''' </todo>
    ''' <port>
    ''' Remove users().connected from below _
    ''' system.net.networkInformation.Ping will be less intensive
    ''' </port>
    ''' -----------------------------------------------------------------------------
    Public Function findOpenUser() As Integer
        SyncLock Users.SyncRoot
            'Clean user's Array here
            Dim iMax As Int32 = Users.GetUpperBound(0)
            Do
                'While (IIf(Users(iMax) Is Nothing, True, _
                '              IIf(Users(iMax).SocketRef Is Nothing, True, _
                '              Not Users(iMax).SocketRef.Poll(250, Net.Sockets.SelectMode.SelectRead)))) Or iMax >= 0
                If Not Users(iMax) Is Nothing Then
                    If Not Users(iMax).SocketRef Is Nothing Then
                        If Users(iMax).Connected Then
                            Exit Do
                        End If
                    End If
                End If
                If frmServer.txtLog.Text.IndexOf(vbNewLine) >= 0 Then _
                  Display("It appears that socket # " + Users(iMax).ConID.ToString _
                  + " has disconnected without a LOGOUT or DISCONNECT. Closing now...")
                If Not Users(iMax) Is Nothing Then
                    If Not Users(iMax).Username Is Nothing Then
                        htUsers.Remove(Users(iMax).Username)
                    End If
                    Users(iMax).Close()
                    Users(iMax) = Nothing
                End If
                If Not iMax = 0 Then ReDim Preserve Users(Users.GetUpperBound(0) - 1)
                iMax -= 1
                If iMax < 0 Then Exit Do
            Loop
            'If Users(0) Is Nothing Then Users(0) = New clsUser
            'If there are no users currently in the array
            If Users.GetUpperBound(0) = 0 Then
                If Not Users(0) Is Nothing Then
                    If Not Users(0).SocketRef Is Nothing Then
                        If Not Users(0).SocketRef.Connected Then
                            Users(0).Close()
                            'Set the first array element to a new instance of User
                            Users(0) = New clsUser(0)
                            'send 0 back to the main code execution
                            findOpenUser = 0
                            'Dont execute anything else in this function
                            Exit Function
                        End If 'Users.GetUpperBound(0) = 0 And Users(0).Connection Is Nothing
                    Else
                        Users(0).Close()
                        'Set the first array element to a new instance of User
                        Users(0) = New clsUser(0)
                        'send 0 back to the main code execution
                        findOpenUser = 0
                        'Dont execute anything else in this function
                        Exit Function
                    End If
                Else
                    'Users(0).Close()
                    'Set the first array element to a new instance of User
                    Users(0) = New clsUser(0)
                    'send 0 back to the main code execution
                    findOpenUser = 0
                    'Dont execute anything else in this function
                    Exit Function
                End If
            End If
            'Loop through all of the elements in the array
            For x As Integer = 0 To Users.GetUpperBound(0)
                'If there is no connection
                If Not Users(x).Connected Then
                    'If lstUsers.Items.Contains(Users(x).Username + " (" + Users(x).IP + ")") Then
                    'Me.OnDisconnected(Users(x))
                    'End If
                    If x > Users.GetUpperBound(0) Then
                        findOpenUser = findOpenUser()
                        Exit Function
                    End If
                    Users(x).Close()
                    'Set this element to a new instance of user
                    Users(x) = New clsUser(x)
                    'send this index (x) back to the main code execution
                    findOpenUser = x
                    'Dont execute anything else in this function
                    Exit Function
                End If 'Users(x).Connection Is Nothing
            Next 'x= 0 To Users.GetUpperBound(0)
            'Redimension the array by 1 more element
            ReDim Preserve Users(Users.GetUpperBound(0) + 1)
            'Set this new element to a new instance of user
            Users(Users.GetUpperBound(0)) = New clsUser(Users.GetUpperBound(0))
            'send this index (Users.GetUpperBound(0)) back to the main code execution
            findOpenUser = Users.GetUpperBound(0)
        End SyncLock
    End Function 'findOpenUser()
#End Region 'Methods
End Module 'modMain